﻿using System;
using System.Linq;

namespace UtilZ.Dotnet.Ex.Json
{
    /// <summary>
    /// json序列化辅助类
    /// </summary>
    public class JsonHelper
    {
        /// <summary>
        /// 判断json值是否为null[为null返回true;否则返回false]
        /// </summary>
        /// <param name="jsonValue">json值</param>
        /// <returns>为null返回true;否则返回false</returns>
        public static bool IsNull(string jsonValue)
        {
            return string.Equals(jsonValue, JsonConstants.NULL, StringComparison.OrdinalIgnoreCase);
        }

        /// <summary>
        /// 判断json值是否仅有值[仅有值返回true;否则返回false]
        /// </summary>
        /// <param name="jsonValue">json值</param>
        /// <returns>仅有值返回true;否则返回false</returns>
        public static bool OnlyValue(string jsonValue)
        {
            if (string.IsNullOrWhiteSpace(jsonValue))
            {
                return true;
            }

            if (jsonValue.Contains('[') || jsonValue.Contains('{'))
            {
                return false;
            }

            return true;
        }


        /// <summary>
        /// 验证类型值是否允许为null[返回值:true:允许为null:false:不允许为null:]
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException"></exception>
        public static bool AllowNull(Type type)
        {
            if (type == null)
            {
                throw new ArgumentNullException(nameof(type));
            }

            if (type.IsClass)
            {
                return true;
            }

            return Nullable.GetUnderlyingType(type) != null;
        }




        /**********************************************************************
         * json字符串中的双引号(")和左斜杠(\)需要要转义
         * eg: {成都"a:b\c,c}  = > "{成都\"a:b\\c,c}"
         * 
         * 对象值 -> json值字符串转义步骤:
         * objValue -> string -> 转义 -> jsonString
         * 
         * json值字符串转义 -> 对象值反转义步骤:
         * 分离到jsonString -> 反转义 -> string -> objValue
         *********************************************************************/

        /// <summary>
        /// 对象值字符串 -> json值字符串
        /// </summary>
        /// <param name="valueStr">对象值字符串</param>
        /// <returns>json值字符串</returns>
        public static string Escape(string valueStr)
        {
            if (string.IsNullOrEmpty(valueStr))
            {
                return valueStr;
            }

            return valueStr.Replace(@"\", @"\\").Replace(@"""", @"\""");
        }


        /// <summary>
        /// json值字符串 -> 对象值字符串
        /// </summary>
        /// <param name="tokenQuoteMarkType">token引号类型</param>
        /// <param name="jsonValue">json值字符串</param>
        /// <returns>对象值字符串</returns>
        public static string DeEscape(TokenQuoteMarkType tokenQuoteMarkType, string jsonValue)
        {
            if (string.IsNullOrEmpty(jsonValue))
            {
                return jsonValue;
            }

            switch (tokenQuoteMarkType)
            {
                case TokenQuoteMarkType.DoubleQuoteMark:
                    return jsonValue.Replace("\\\\", "\\").Replace("\\\"", "\"");
                case TokenQuoteMarkType.SingleQuoteMark:
                    return jsonValue.Replace("\\\\", "\\").Replace("\\\'", "'");
                case TokenQuoteMarkType.None:
                default:
                    return jsonValue.Replace("\\\\", "\\");
            }
        }




        /// <summary>
        /// 跳过注释
        /// </summary>
        /// <param name="commentType"></param>
        /// <param name="json"></param>
        /// <param name="index"></param>
        public static void IgnoreComment(JsonCommentType commentType, ref string json, ref int index)
        {
            //跳过注释
            switch (commentType)
            {
                case JsonCommentType.SlashStar:
                    for (int j = index + 2; j < json.Length; j++)
                    {
                        if (json[j] == '*' && json[j + 1] == '/')
                        {
                            index = j + 2;
                            break;
                        }
                    }
                    break;
                case JsonCommentType.DoubleSlash:
                    for (int j = index + 2; j < json.Length; j++)
                    {
                        if (json[j] == '\n' && json[j + 1] != '\n')
                        {
                            index = j + 1;
                            break;
                        }
                    }
                    break;
            }
        }

        /// <summary>
        /// 判断是否以注释开始
        /// </summary>
        /// <param name="json"></param>
        /// <param name="index"></param>
        /// <returns></returns>
        public static JsonCommentType CommentBegin(ref string json, int index)
        {
            if (json[index] == '/' && json[index + 1] == '*')
            {
                return JsonCommentType.SlashStar;
            }
            else if (json[index] == '/' && json[index + 1] == '/')
            {
                return JsonCommentType.DoubleSlash;
            }
            else
            {
                return JsonCommentType.None;
            }
        }
    }
}
